
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;

namespace Fcdbas.Core.Windows
{
	public class SalContext : System.IDisposable
	{
		[System.ThreadStatic]
		private static Stack<SalContext> m_stack;
		[System.ThreadStatic]
		private static SalContext m_last;
		private System.Windows.Forms.Control m_control;
		private SalWindowHandle m_hWndMDI = SalWindowHandle.Null;
		private SalWindowHandle m_hWndItem = SalWindowHandle.Null;
		private SalWindowHandle m_hWndForm = SalWindowHandle.Null;
		private bool m_disposed;
		private bool m_pushed;
		private bool m_root;
		private int m_actionsIndex = -1;
		
		internal static SalContext Current
		{
			get
			{
				SalContext.EnsureStack();
				return SalContext.m_stack.Peek();
			}
		}
		internal System.Windows.Forms.Control Control
		{
			get
			{
				return this.m_control;
			}
		}
		internal int WindowActionsIndex
		{
			get
			{
				return this.m_actionsIndex;
			}
			set
			{
				this.m_actionsIndex = value;
			}
		}
		public bool Disposed
		{
			get
			{
				return this.m_disposed;
			}
		}
		[System.Diagnostics.DebuggerStepThrough]
		internal SalContext()
		{
			if (SalContext.m_stack == null)
			{
				SalContext.m_stack = new Stack<SalContext>();
				SalContext.Push(new SalContext());
			}
		}
		[System.Diagnostics.DebuggerStepThrough]
		internal SalContext(SalContext cx)
		{
			this.m_control = cx.m_control;
			this.m_hWndMDI = cx.m_hWndMDI;
			this.m_hWndForm = cx.m_hWndForm;
			this.m_hWndItem = cx.m_hWndItem;
			SalContext.Push(this);
		}
		[System.Diagnostics.DebuggerStepThrough]
		public SalContext(System.Windows.Forms.Control ctrl) : this(ctrl, null, false)
		{
		}
		[System.Diagnostics.DebuggerStepThrough]
		public SalContext(System.Windows.Forms.Control ctrl, bool root) : this(ctrl, null, root)
		{
		}
		[System.Diagnostics.DebuggerStepThrough]
		public SalContext(System.Windows.Forms.Control ctrl, object locals) : this(ctrl, locals, false)
		{
		}
		[System.Diagnostics.DebuggerStepThrough]
		internal SalContext(System.Windows.Forms.Control ctrl, object locals, bool root)
		{
			if (SalContext.m_stack == null)
			{
				SalContext.m_stack = new Stack<SalContext>();
				SalContext.Push(new SalContext());
			}
			this.m_root = root;
			ctrl = SalWindow.TranslateControl(ctrl);
			if (ctrl == null)
			{
				SalContext.Push(this);
				return;
			}
			if (ctrl.IsHandleCreated && this.LoadContext(ctrl, locals, root))
			{
				SalContext.Push(this);
			}
			
		}
		private bool LoadContext(System.Windows.Forms.Control ctrl, object locals, bool root)
		{
			if (!root && SalContext.m_last != null && SalContext.m_last.m_control == ctrl)
			{
				SalContext last = SalContext.m_last;
				this.m_control = last.m_control;
				this.m_hWndMDI = last.m_hWndMDI;
				this.m_hWndForm = last.m_hWndForm;
				this.m_hWndItem = last.m_hWndItem;
				Sys.hWndMDI = last.m_hWndMDI;
				Sys.hWndForm = last.m_hWndForm;
				Sys.hWndItem = last.m_hWndItem;
				return true;
			}
			this.LoadSystemVars(ctrl);
			if (!root && SalContext.m_last != null && SalContext.m_last.m_root && ctrl.HasChildren)
			{
				int controlTypeInternal = SalWindow.GetControlTypeInternal(SalContext.m_last.m_control);
				switch (controlTypeInternal)
				{
				case 1:
				case 2:
				case 4:
					goto IL_EA;
				case 3:
					break;
				default:
					if (controlTypeInternal == 524288 || controlTypeInternal == 1048576)
					{
						goto IL_EA;
					}
					break;
				}
				if (SalWindow.GetParent(SalContext.m_last.m_control) == ctrl)
				{
					this.m_hWndItem = Sys.hWndItem;
				}
			}
			IL_EA:
			Sys.hWndMDI = this.m_hWndMDI;
			Sys.hWndForm = this.m_hWndForm;
			Sys.hWndItem = this.m_hWndItem;
			return true;
		}
		private static void Push(SalContext cx)
		{
			SalContext.EnsureStack();
			SalContext.m_last = cx;
			SalContext.m_stack.Push(cx);
			cx.m_pushed = true;
			Sys.hWndMDI = cx.m_hWndMDI;
			Sys.hWndForm = cx.m_hWndForm;
			Sys.hWndItem = cx.m_hWndItem;
		}
		private static void Pop()
		{
			if (SalContext.m_stack != null && SalContext.m_stack.Count > 0)
			{
				SalContext.m_stack.Pop();
				SalContext current = SalContext.Current;
				SalContext.m_last = current;
				Sys.hWndMDI = current.m_hWndMDI;
				Sys.hWndForm = current.m_hWndForm;
				Sys.hWndItem = current.m_hWndItem;
			}
		}
		private static void EnsureStack()
		{
			if (SalContext.m_stack == null)
			{
				SalContext.m_stack = new Stack<SalContext>(100);
			}
			if (SalContext.m_stack.Count == 0)
			{
				SalContext.m_stack.Push(new SalContext());
			}
		}
		private void LoadSystemVars(System.Windows.Forms.Control target)
		{
			this.m_control = target;
			this.m_hWndMDI = Sys.hWndNULL;
			this.m_hWndItem = Sys.hWndNULL;
			this.m_hWndForm = Sys.hWndNULL;
			if (!SalWindow.IsReadyToDispatch(target))
			{
				return;
			}
			this.LoadVarsMDI(target);
			if (target is System.Windows.Forms.Form && this.LoadVarsForm(target))
			{
				return;
			}
			
			this.LoadVarsControl(target);
		}
		private void LoadVarsMDI(System.Windows.Forms.Control control)
		{
			System.Windows.Forms.Form form = control.TopLevelControl as System.Windows.Forms.Form;
			while (form != null && !form.IsMdiContainer && !form.IsMdiChild)
			{
				System.Windows.Forms.Form form2 = form.Owner;
				if (form2 == null && form.Disposing && form is ISalForm)
				{
					form2 = ((ISalForm)form).SavedOwner;
				}
				form = ((form2 == null) ? null : (form2.TopLevelControl as System.Windows.Forms.Form));
			}
			if (form != null)
			{
				System.Windows.Forms.Form form3 = form.IsMdiChild ? form.MdiParent : form;
				this.m_hWndMDI = form3;
				System.Windows.Forms.Form activeMdiChild = form3.ActiveMdiChild;
				if (activeMdiChild != null)
				{
					this.m_hWndForm = activeMdiChild;
				}
				this.m_hWndItem = this.m_hWndMDI;
			}
		}
		private bool LoadVarsForm(System.Windows.Forms.Control control)
		{
			System.Windows.Forms.Form form = (System.Windows.Forms.Form)control;
			if (form.IsMdiContainer)
			{
				return false;
			}
			this.m_hWndForm = control;
			this.m_hWndItem = this.m_hWndForm;
			return true;
		}
		private bool LoadVarsTableWindow(System.Windows.Forms.Control control)
		{
			this.m_hWndForm = control;
			this.m_hWndItem = this.m_hWndForm;
			return true;
		}
		
		private void LoadVarsControl(System.Windows.Forms.Control control)
		{
			System.Windows.Forms.Form form = control.FindForm();
			if (form != null && !form.IsMdiContainer)
			{
				this.m_hWndForm = form;
			}
			this.m_hWndItem = control;
		}
		public void Dispose()
		{
			if (this.m_disposed)
			{
				throw new System.InvalidOperationException(Sys.GetString("SalContextAlreadyDisposed"));
			}
			this.m_control = null;
			this.m_disposed = true;
			if (this.m_pushed)
			{
				SalContext.Pop();
			}
			
		}
	}
}
